import axios, { AxiosInstance, AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';

interface FSResponse<T = any> extends AxiosResponse<T> {
  code: number;
  result: any;
  message: string;
  errors: any;
  success: any;
}

interface FSPromise<T = any> extends Omit<AxiosPromise<T>, 'then'|'catch'|'finally'>, Promise<FSResponse<T>> {}

export interface CustomRequestConfig extends AxiosRequestConfig {
  prefix?: string;
  reqType?: string;
  isPuAjax?: boolean;
}

interface FsAxiosInstance extends AxiosInstance {
  getFn<T = any, R = FSResponse<T>>(
    url: string,
    config?: CustomRequestConfig,
  ): FSPromise<R>;
  postFn<T = any, R = FSResponse<T>>(
    url: string,
    data?: any,
    config?: CustomRequestConfig,
  ): FSPromise<R>;
  fsDownloadFile(url: string, type: string, data?: any): Promise<void>;
}

const axiosInstance = axios.create({
  baseURL: '/',
  timeout: 0,
  responseType: 'json',
  withCredentials: false,
  responseEncoding: 'utf8',
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
  },
  // paramsSerializer: params => Qs.stringify(params, {arrayFormat: 'brackets'})
}) as FsAxiosInstance;

axiosInstance.interceptors.request.use(
  config => config,
  error => Promise.reject(error)
);

axiosInstance.interceptors.response.use(
  response => response?.data,
  error => Promise.reject(error?.data)
);

axiosInstance.getFn = (url: string, config?: CustomRequestConfig) => axiosInstance.get(url, config).catch((err: any) => err);

axiosInstance.postFn = (url: string, data, config?: CustomRequestConfig) => axiosInstance.post(url, data, config).catch((err: any) => err);

export const ajaxGet = axiosInstance.getFn;
export const ajaxPost = axiosInstance.postFn;